/*****************************************Copyright(C)******************************************
****************************************** *********************************************
*------------------------------------------文件信息---------------------------------------------
* FileName          : Bsp_flash.c
* Author            : 张婷颖
* Version           : 1.0V
* Description       :
*----------------------------------------历史版本信息-------------------------------------------
* History           :
* Description       :
*-----------------------------------------------------------------------------------------------
***********************************************************************************************/
/* Includes-----------------------------------------------------------------------------------*/
#include <Bsp_flash.h>
#include "main.h"
/* Private define-----------------------------------------------------------------------------*/

/* Private typedef----------------------------------------------------------------------------*/

/* Private macro------------------------------------------------------------------------------*/

/* Private variables--------------------------------------------------------------------------*/

/* Private function prototypes----------------------------------------------------------------*/

/* Private functions--------------------------------------------------------------------------*/
/************************************************
函数名称 ： STMFLASH_ReadWord
功    能 ：读取指定该地址数据（32位）
参    数 ：faddr flash地址
返 回 值 ：读取的32位数据
*************************************************/
uint32_t STMFLASH_ReadWord(uint32_t faddr)
{
	return *(__IO uint32_t *)faddr;                                //
}

/************************************************
函数名称 ： STMFLASH_GetFlashSector
功    能 ：获取地址所在扇区
参    数 ：addr flash地址
返 回 值 ：扇区
*************************************************/
uint8_t STMFLASH_GetFlashSector(uint32_t addr)
{
	if(addr<ADDR_FLASH_SECTOR_1)return FLASH_SECTOR_0;
	else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_SECTOR_1;
	else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_SECTOR_2;
	else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_SECTOR_3;
	else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_SECTOR_4;
	else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_SECTOR_5;
	else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_SECTOR_6;
	else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_SECTOR_7;
//	else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_SECTOR_8;
//	else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_SECTOR_9;
//	else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_SECTOR_10;
	return FLASH_SECTOR_11;
}

/************************************************
函数名称 ： STMFLASH_Write
功    能 ：从指定地址开始写入指定长度数据
参    数 ：WriteAddr 写入flash起始地址   pBuffer 写入内容   NumToWrite 写入大小
返 回 值 ：
*************************************************/
void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite)
{
	FLASH_EraseInitTypeDef FlashEraseInit;
	    HAL_StatusTypeDef FlashStatus=HAL_OK;
	    uint32_t SectorError=0;
			uint32_t addrx=0;
			uint32_t endaddr=0;
	    if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;	              //非法地址

			HAL_FLASH_Unlock();             //flash解锁
			addrx=WriteAddr;				//写入起始地址
			endaddr=WriteAddr+NumToWrite*4;	//写入结束地址

	    if(addrx<0X1FFF0000)
	    {
	        while(addrx<endaddr)		                                    //扫清一切障碍，对非0xFFFFFFFF的地方先擦除
			{
				if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)                    //对非0xFFFFFFFF的地方先擦除整个扇区
				{
	                FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型，扇区擦除
	                FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //要擦除的扇区
	                FlashEraseInit.NbSectors=1;                             //一次擦一个扇区
	                FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围，VCC=2.7~3.6v
	                if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)
	                {
	                    break;//发生错误
	                }
				}else addrx+=4;
	            FLASH_WaitForLastOperation(FLASH_WAITETIME);                //等待上次操作完成
	        }
	    }
	    FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME);            //等待上次操作完成
			if(FlashStatus==HAL_OK)
			{
				while(WriteAddr<endaddr)                                   //写数据
				{
					if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
					{
						break;	                                            //写入错误
					}
					WriteAddr+=4;
					pBuffer++;
				}
			}
			HAL_FLASH_Lock();           //flash锁定
}

/************************************************
函数名称 ： STMFLASH_Read
功    能 ：从指定地址开始读取指定长度数据
参    数 ：ReadAddr 读取flash起始地址   pBuffer 读取内容   NumToRead 读取大小
返 回 值 ：
*************************************************/
void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead)
{
	uint32_t i;
	for(i=0;i<NumToRead;i++)
	{
		pBuffer[i]=STMFLASH_ReadWord(ReadAddr);                                 //读取4个字节
		ReadAddr+=4;                                                            //偏移4字节
	}
}



